import { initState } from './initState.js'
import { complieToFunctions } from './compiler/index.js'
import { mountComponent, callHook } from './lifecycle.js'
import { nextTick, mergeOptions } from './utils.js'

//实例初始化
export function initMixin(Vue) {
    //初始化原型方法
    //debugger
    Vue.prototype._init = function (options) {
        //console.log(options);
        //将当前的实例对象,保存在vm变量中
        //this指向的是new后的实例对象
        const vm = this;
        //实例的$options方法为当前用户传入options配置对象
        //vm.$options = options;
        //实例的$options方法为   当前用户传入options配置对象+Vue的静态属性options
        vm.$options = mergeOptions(vm.constructor.options, options);
        //console.log(vm.$options);
        //发布生命周期函数---beforeCreate
        callHook(vm, 'beforeCreate')
        //初始化状态,将当前实例对象vm传入方法
        initState(vm);
        //发布生命周期函数---created
        callHook(vm, 'created')
        //如果用户的配置信息中存在el属性,调用原型方法$mount()
        if (vm.$options.el) vm.$mount(vm.$options.el);
    };
    //定义原型方法 $nextTick 用来获取异步执行更新渲染函数
    Vue.prototype.$nextTick = nextTick;

    //定义原型方法 $mount
    Vue.prototype.$mount = function (el) {

        //获取dom元素
        el = el && document.querySelector(el)
        //获取当前实例
        const vm = this;
        //获取用户的配置项
        const options = vm.$options;
        vm.$el = el;
        //用户的配置项options不存在reder属性,则自定义render方法
        if (!options.render) {
            //获取用户的配置项中的template属性(用户以下方式获取模板)
            /* 
            const vm= new Vue({
            el:'#app',
            data() {
                return {
                    name:'jxw',
                    mes:'你好'
                }
            },
            template:'<ul>
                <li>{{name}}</li>
                <li>{{mes}}</li>
            </ul>'
        });
             */
            let template = options.template;
            if (!template && el) {
                //如果template属性又不存在且el存在(用户以下方式获取模板)
                /*<div id="app">
                    <ul>
                        <li>{{name}}</li>
                        <li>{{mes}}</li>
                    </ul>
                </div>
                const vm= new Vue({
                el:'#app',
                data() {
                    return {
                        name:'jxw',
                        mes:'你好'
                    }
                }*/
                //outerHTML设置或获取对象及其内容的HTML形式
                template = el.outerHTML;
            }

            //解析html模板=>ast语法树=>render函数
            const render = complieToFunctions(template);
            //暴露这个render函数
            options.render = render;
            //console.log(options.render);
        }
        //console.log(vm);
        mountComponent(vm)//组件渲染
    }



}
